package com.fastgwt.client;

import java.util.ArrayList;
import java.util.List;

import com.fastgwt.client.cmp.GwtContainer;
import com.fastgwt.client.model.EmployeeProperties;
import com.fastgwt.client.mvc.controller.EmployeeController;
import com.fastgwt.client.mvc.controller.EmployeeQueryController;
import com.fastgwt.shared.dto.Employee;
import com.fastgwt.shared.services.EmployeeService;
import com.fastgwt.shared.services.EmployeeServiceAsync;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.text.shared.SimpleSafeHtmlRenderer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.sencha.gxt.cell.core.client.SimpleSafeHtmlCell;
import com.sencha.gxt.cell.core.client.form.ComboBoxCell.TriggerAction;
import com.sencha.gxt.core.client.GXT;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.core.client.util.Margins;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.StringLabelProvider;
import com.sencha.gxt.data.shared.TreeStore;
import com.sencha.gxt.examples.resources.client.TestData;
import com.sencha.gxt.examples.resources.client.images.ExampleImages;
import com.sencha.gxt.examples.resources.client.model.BaseDto;
import com.sencha.gxt.examples.resources.client.model.FolderDto;
import com.sencha.gxt.examples.resources.client.model.StockProperties;
import com.sencha.gxt.state.client.CookieProvider;
import com.sencha.gxt.state.client.GridStateHandler;
import com.sencha.gxt.state.client.StateManager;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.FramedPanel;
import com.sencha.gxt.widget.core.client.box.MessageBox;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.AbstractHtmlLayoutContainer.HtmlData;
import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer;
import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer.BorderLayoutData;
import com.sencha.gxt.widget.core.client.container.HtmlLayoutContainer;
import com.sencha.gxt.widget.core.client.container.MarginData;
import com.sencha.gxt.widget.core.client.container.SimpleContainer;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
import com.sencha.gxt.widget.core.client.container.Viewport;
import com.sencha.gxt.widget.core.client.event.RowDoubleClickEvent;
import com.sencha.gxt.widget.core.client.event.RowDoubleClickEvent.RowDoubleClickHandler;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
import com.sencha.gxt.widget.core.client.form.FieldLabel;
import com.sencha.gxt.widget.core.client.form.FieldSet;
import com.sencha.gxt.widget.core.client.form.FormPanel.LabelAlign;
import com.sencha.gxt.widget.core.client.form.FormPanelHelper;
import com.sencha.gxt.widget.core.client.form.NumberField;
import com.sencha.gxt.widget.core.client.form.NumberPropertyEditor;
import com.sencha.gxt.widget.core.client.form.SimpleComboBox;
import com.sencha.gxt.widget.core.client.form.TextField;
import com.sencha.gxt.widget.core.client.grid.CellSelectionModel;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.sencha.gxt.widget.core.client.grid.GridSelectionModel;
import com.sencha.gxt.widget.core.client.info.Info;
import com.sencha.gxt.widget.core.client.selection.CellSelectionChangedEvent;
import com.sencha.gxt.widget.core.client.selection.CellSelectionChangedEvent.CellSelectionChangedHandler;
import com.sencha.gxt.widget.core.client.tips.QuickTip;
import com.sencha.gxt.widget.core.client.toolbar.LabelToolItem;
import com.sencha.gxt.widget.core.client.toolbar.ToolBar;
import com.sencha.gxt.widget.core.client.tree.Tree;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Fastgwt implements IsWidget, EntryPoint, Editor<Employee> {
	// controllers
	private EmployeeController employeeController = new EmployeeController();
	private EmployeeQueryController employeeQueryController = new EmployeeQueryController();
	private static final int COLUMN_FORM_WIDTH = 1000;
	private FramedPanel createEmployeeForm;
	private static final StockProperties props = GWT
			.create(StockProperties.class);

	private static final EmployeeProperties props2 = GWT
			.create(EmployeeProperties.class);
	private ContentPanel root;
	private EmployeeServiceAsync employeeService;
	final TextField job = new TextField();
	final TextField email = new TextField();
	final NumberField<Long> employeeId = new NumberField<Long>(
			new NumberPropertyEditor.LongPropertyEditor());
	final TextField employeeSurname = new TextField();
	final TextField employeeName = new TextField();

	final GwtContainer center = GwtContainer.getInstance();

	interface EmployeeDriver extends SimpleBeanEditorDriver<Employee, Fastgwt> {
	}

	private EmployeeDriver driver = GWT.create(EmployeeDriver.class);

	// interface StockTemplate extends XTemplates {
	// @XTemplate(source = "BasicBindingExample.html")
	// SafeHtml drawStock(Stock stock);
	// }

	class KeyProvider implements ModelKeyProvider<BaseDto> {
		@Override
		public String getKey(BaseDto item) {
			return (item instanceof FolderDto ? "f-" : "m-")
					+ item.getId().toString();
		}
	}

	@Override
	public Widget asWidget() {

		final BorderLayoutContainer con = new BorderLayoutContainer();
		con.setBorders(true);
		ContentPanel west = new ContentPanel();

		// west.setHeadingText("Menu");
		// west.setPixelSize(315, 400);
		// west.addStyleName("margin-10");
		// center.setResize(false);

		// center.add(con);

		TreeStore<BaseDto> store = new TreeStore<BaseDto>(new KeyProvider());

		FolderDto root = TestData.getMenuRootFolder();
		for (BaseDto base : root.getChildren()) {
			store.add(base);
			if (base instanceof FolderDto) {
				processFolder(store, (FolderDto) base);
			}
		}

		SimpleSafeHtmlCell<String> cell = new SimpleSafeHtmlCell<String>(
				SimpleSafeHtmlRenderer.getInstance(), "click") {
			@Override
			public void onBrowserEvent(Context context, Element parent,
					String value, NativeEvent event,
					ValueUpdater<String> valueUpdater) {
				super.onBrowserEvent(context, parent, value, event,
						valueUpdater);
				if ("click".equals(event.getType())) {
					Info.display("Click", "You clicked \"" + value + "\"!");

					if (value.equals("Create Employee")) {
						// if (createEmployeeForm == null) {
						// createEmployeeForm = createForm2();
						// driver.initialize(Fastgwt.this);
						// }
						center.setWidget(employeeController.getView());
						// driver.edit(new Employee());

						// createEmployeeForm.show();
						employeeController.getView().show();
					} else if (value.equals("List Employees")) {
						if (createEmployeeForm != null)
							createEmployeeForm.hide();
//						center.setWidget(listEmployers());
						 center.setWidget(employeeQueryController.getView());
						 employeeQueryController.getView().show();
					}
				}
			}
		};

		final Tree<BaseDto, String> tree = new Tree<BaseDto, String>(store,
				new ValueProvider<BaseDto, String>() {

					@Override
					public String getValue(BaseDto object) {
						return object.getName();
					}

					@Override
					public void setValue(BaseDto object, String value) {

					}

					@Override
					public String getPath() {
						return "name";
					}
				});
		tree.setCell(cell);
		tree.setWidth(300);
		tree.getStyle().setLeafIcon(ExampleImages.INSTANCE.form());

		ToolBar buttonBar = new ToolBar();

		buttonBar.add(new TextButton("Expand All", new SelectHandler() {

			@Override
			public void onSelect(SelectEvent event) {
				tree.expandAll();
			}
		}));
		buttonBar.add(new TextButton("Collapse All", new SelectHandler() {
			@Override
			public void onSelect(SelectEvent event) {
				tree.collapseAll();
			}

		}));

		// con.add(buttonBar, new VerticalLayoutData(1, -1));
		// con.add(tree, new VerticalLayoutData(1, 1));
		// west.add(buttonBar);
		west.add(tree);

		BorderLayoutData westData = new BorderLayoutData(150);
		westData.setCollapsible(true);
		westData.setSplit(true);
		westData.setCollapseMini(true);
		westData.setMargins(new Margins(0, 5, 0, 5));

		MarginData centerData = new MarginData();
		con.setWestWidget(west, westData);
		con.setCenterWidget(center, centerData);

		// SimpleContainer simple = new SimpleContainer();
		// simple.add(con, new MarginData(10));

		return con;
	}

	// private FramedPanel createForm2() {
	// FramedPanel form2 = new FramedPanel();
	// form2.setHeadingText("Create Emplyee");
	// form2.setWidth(350);
	//
	// FieldSet fieldSet = new FieldSet();
	// fieldSet.setHeadingText("User Information");
	// fieldSet.setCollapsible(true);
	// form2.add(fieldSet);
	//
	// VerticalLayoutContainer p = new VerticalLayoutContainer();
	// fieldSet.add(p);
	//
	// employeeId.setAllowBlank(false);
	//
	// p.add(new FieldLabel(employeeId, "Employee Id"),
	// new VerticalLayoutData(1, -1));
	//
	// employeeName.setAllowBlank(false);
	// p.add(new FieldLabel(employeeName, "First Name"),
	// new VerticalLayoutData(1, -1));
	//
	// employeeSurname.setAllowBlank(false);
	// p.add(new FieldLabel(employeeSurname, "Last Name"),
	// new VerticalLayoutData(1, -1));
	//
	// job.setAllowBlank(false);
	// p.add(new FieldLabel(job, "Job desc."), new VerticalLayoutData(1, -1));
	//
	// p.add(new FieldLabel(email, "Email"), new VerticalLayoutData(1, -1));
	//
	// TextButton btn = new TextButton("Save");
	// btn.addSelectHandler(new SelectHandler() {
	//
	// @Override
	// public void onSelect(SelectEvent event) {
	// Employee emp = new Employee();
	// // emp.setEmployeeId(Long.parseLong( idText.getText()));
	// // emp.setEmployeeName(firstName.getText());
	// // emp.setEmployeeSurname(lastName.getText());
	// // emp.setEmail(email.getText());
	//
	// driver.flush();
	// emp = driver.flush();
	// Info.display("emp", emp.toString());
	// if (driver.hasErrors()) {
	// new MessageBox("Please correct the errors before saving.")
	// .show();
	// return;
	// }
	// employeeService.saveOrUpdateEmployee(emp,
	// new AsyncCallback<Employee>() {
	// public void onFailure(Throwable caught) {
	// // Show the RPC error message to the user
	//
	// Info.display("failed", "rpc is failed");
	// }
	//
	// public void onSuccess(Employee emp) {
	// Info.display("succes",
	// "Employee is saved name " + emp);
	// }
	// });
	//
	// }
	// });
	// form2.addButton(btn);
	//
	// form2.addButton(new TextButton("Cancel"));
	//
	// return form2;
	// }
//
//	private FramedPanel createFormForEmployeeQueryCriteria(TextButton listBtn,
//			TextButton clearBtn, TextField firstName, TextField lastName,
//			TextField job) {
//		FramedPanel panel = new FramedPanel();
//		// panel.setHeadingText("Employee Query");
//		// panel.setWidth(350);
//		// panel.setBodyStyle("background: none; padding: 5px");
//		panel.setWidth(COLUMN_FORM_WIDTH);
//
//		HtmlLayoutContainer con = new HtmlLayoutContainer(getTableMarkup());
//		panel.setWidget(con);
//		int cw = (COLUMN_FORM_WIDTH / 2) - 12;
//		// firstName.setAllowBlank(false);
//		firstName.setEmptyText("Enter name...");
//		firstName.setWidth(cw);
//
//		// lastName.setAllowBlank(false);
//		lastName.setEmptyText("Enter last name...");
//		lastName.setWidth(cw);
//
//		// job.setAllowBlank(false);
//		job.setEmptyText("Enter job description...");
//		job.setWidth(cw);
//
//		con.add(new FieldLabel(firstName, "First Name"), new HtmlData(".fn"));
//
//		con.add(new FieldLabel(lastName, "Last Name"), new HtmlData(".ln"));
//
//		con.add(new FieldLabel(job, "Job Description"), new HtmlData(".job"));
//
//		// ContentPanel panel = new ContentPanel(
//		// GWT.<ContentPanelAppearance> create(FramedPanelAppearance.class));
//		// panel.setBodyStyle("padding: 5px");
//
//		// panel.add(p);
//		panel.addButton(listBtn);
//		panel.addButton(clearBtn);
//
//		List<FieldLabel> labels = FormPanelHelper.getFieldLabels(panel);
//		for (FieldLabel lbl : labels) {
//			lbl.setLabelAlign(LabelAlign.TOP);
//		}
//
//		return panel;
//	}
//
//	public Widget listEmployers() {
//		ColumnConfig<Employee, String> nameCol = new ColumnConfig<Employee, String>(
//				props2.employeeName(), 50, "Name");
//
//		ColumnConfig<Employee, String> surnameCol = new ColumnConfig<Employee, String>(
//				props2.employeeSurname(), 50, "Surname");
//
//		ColumnConfig<Employee, String> jobCol = new ColumnConfig<Employee, String>(
//				props2.job(), 50, "Job");
//
//		ColumnConfig<Employee, String> emailCol = new ColumnConfig<Employee, String>(
//				props2.email(), 150, "Email");
//
//		List<ColumnConfig<Employee, ?>> l = new ArrayList<ColumnConfig<Employee, ?>>();
//		l.add(nameCol);
//		l.add(surnameCol);
//		l.add(jobCol);
//		l.add(emailCol);
//		ColumnModel<Employee> cm = new ColumnModel<Employee>(l);
//
//		final ListStore<Employee> store = new ListStore<Employee>(props2.key());
//
//		try {
//			employeeService.listAll(new AsyncCallback<List<Employee>>() {
//
//				@Override
//				public void onFailure(Throwable arg0) {
//					// TODO Auto-generated method stub
//
//				}
//
//				@Override
//				public void onSuccess(List<Employee> arg0) {
//					store.clear();
//					store.addAll(arg0);
//
//				}
//			});
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//
//		root = new ContentPanel();
//		root.setHeadingText("List Employees");
//		root.getHeader().setIcon(ExampleImages.INSTANCE.table());
//		// root.setPixelSize(600, 300);
//		root.setWidth(COLUMN_FORM_WIDTH);
//		root.addStyleName("margin-10");
//
//		// ToolButton info = new ToolButton(ToolButton.QUESTION);
//		// ToolTipConfig config = new ToolTipConfig("Example Info",
//		// "This examples includes resizable panel, reorderable columns and grid state.");
//		// config.setMaxWidth(225);
//		// info.setToolTipConfig(config);
//		// root.addTool(info);
//
//		// Resizable r = new Resizable(root, Dir.E, Dir.SE, Dir.S);
//		// r.setMinHeight(200);
//		// r.setMinWidth(300);
//
//		final Grid<Employee> grid = new Grid<Employee>(store, cm);
//		grid.getView().setAutoExpandColumn(nameCol);
//		grid.getView().setStripeRows(true);
//		grid.getView().setColumnLines(true);
//		grid.setBorders(false);
//
//		grid.setColumnReordering(true);
//		grid.setStateful(true);
//		grid.setStateId("gridExample");
//		grid.addRowDoubleClickHandler(new RowDoubleClickHandler() {
//
//			@Override
//			public void onRowDoubleClick(RowDoubleClickEvent event) {
//				driver.initialize(Fastgwt.this);
//				driver.edit(store.get(event.getRowIndex()));
//				if (createEmployeeForm == null)
//					createEmployeeForm = createForm2();
//				center.setWidget(createEmployeeForm);
//				createEmployeeForm.show();
//
//			}
//		});
//		GridStateHandler<Employee> state = new GridStateHandler<Employee>(grid);
//		state.loadState();
//
//		VerticalLayoutContainer con = new VerticalLayoutContainer();
//		root.setWidget(con);
//
//		// con.add(toolBar, new VerticalLayoutData(1, -1));
//
//		TextButton listBtn = new TextButton("List");
//
//		final TextField firstName = new TextField();
//		final TextField lastName = new TextField();
//		final TextField job = new TextField();
//		listBtn.addSelectHandler(new SelectHandler() {
//
//			@Override
//			public void onSelect(SelectEvent event) {
//
//				try {
//					// Info.display("firstName", firstName.getValue());
//					employeeService.listAll(firstName.getValue(),
//							lastName.getValue(), job.getValue(),
//							new AsyncCallback<List<Employee>>() {
//
//								@Override
//								public void onFailure(Throwable arg0) {
//									// TODO Auto-generated method stub
//									Info.display("failed", "rpc is failed");
//								}
//
//								@Override
//								public void onSuccess(List<Employee> arg0) {
//									store.clear();
//									store.addAll(arg0);
//
//								}
//							});
//				} catch (Exception e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
//
//			}
//		});
//
//		TextButton clearBtn = new TextButton("Clear");
//		clearBtn.addSelectHandler(new SelectHandler() {
//
//			@Override
//			public void onSelect(SelectEvent event) {
//				// TODO Auto-generated method stub
//				store.clear();
//			}
//		});
//		VerticalPanel vp = new VerticalPanel();
//		vp.add(createFormForEmployeeQueryCriteria(listBtn, clearBtn, firstName,
//				lastName, job));
//		// vp.add(toolBar);
//		ToolBar toolBar = new ToolBar();
//		// toolBar.add(createFormForEmployeeQueryCriterias(listBtn, clearBtn,
//		// firstName, lastName, job));
//
//		toolBar.add(new LabelToolItem("Selection Mode: "));
//
//		SimpleComboBox<String> type = new SimpleComboBox<String>(
//				new StringLabelProvider<String>());
//		type.setTriggerAction(TriggerAction.ALL);
//		type.setEditable(false);
//		type.setWidth(100);
//		type.add("Row");
//		type.add("Cell");
//		type.setValue("Row");
//		// we want to change selection model on select, not value change which
//		// fires on blur
//		type.addSelectionHandler(new SelectionHandler<String>() {
//
//			@Override
//			public void onSelection(SelectionEvent<String> event) {
//				boolean cell = event.getSelectedItem().equals("Cell");
//				if (cell) {
//					CellSelectionModel<Employee> c = new CellSelectionModel<Employee>();
//					c.addCellSelectionChangedHandler(new CellSelectionChangedHandler<Employee>() {
//
//						@Override
//						public void onCellSelectionChanged(
//								CellSelectionChangedEvent<Employee> event) {
//
//						}
//					});
//
//					grid.setSelectionModel(c);
//				} else {
//					grid.setSelectionModel(new GridSelectionModel<Employee>());
//				}
//			}
//		});
//		type.addValueChangeHandler(new ValueChangeHandler<String>() {
//
//			@Override
//			public void onValueChange(ValueChangeEvent<String> event) {
//
//			}
//		});
//		toolBar.add(type);
//		// vp.add(toolBar);
//		vp.add(grid);
//		con.add(vp, new VerticalLayoutData(1, -1));
//
//		// needed to enable quicktips (qtitle for the heading and qtip for the
//		// content) that are setup in the change GridCellRenderer
//		new QuickTip(grid);
//
//		return root;
//	}
//
//	private native String getTableMarkup() /*-{
//		return [
//				'<table width=100% cellpadding=0 cellspacing=0>',
//				'<tr><td class=fn width=120px></td><td class=ln width=120px></td></tr>',
//				'<tr><td class=job width=120px></td><td ></td></tr>',
//
//		].join("");
//	}-*/;

	public void onModuleLoad() {
		// RootPanel.get().add(asWidget());
//
//		StateManager.get().setProvider(
//				new CookieProvider("/", null, null, GXT.isSecure()));
		employeeService = (EmployeeServiceAsync) GWT
				.create(EmployeeService.class);

		Widget con = asWidget();
		Viewport viewport = new Viewport();
		viewport.add(con);
		RootPanel.get().add(viewport);
	}

	private void processFolder(TreeStore<BaseDto> store, FolderDto folder) {
		for (BaseDto child : folder.getChildren()) {
			store.add(folder, child);
			if (child instanceof FolderDto) {
				processFolder(store, (FolderDto) child);
			}
		}
	}
}
